package com.nbsaas.nbmall.cart.rest.resource;

import com.haoxuer.bigworld.gather.api.domain.response.MapResponse;
import com.nbsaas.nbmall.cart.api.apis.CartApi;
import com.nbsaas.nbmall.cart.api.domain.list.CartList;
import com.nbsaas.nbmall.cart.api.domain.page.CartPage;
import com.nbsaas.nbmall.cart.api.domain.request.*;
import com.nbsaas.nbmall.cart.api.domain.response.CartResponse;
import com.nbsaas.nbmall.cart.api.domain.simple.CartSimple;
import com.nbsaas.nbmall.cart.data.dao.CartDao;
import com.nbsaas.nbmall.cart.data.entity.Cart;
import com.nbsaas.nbmall.cart.rest.convert.CartResponseConvert;
import com.nbsaas.nbmall.cart.rest.convert.CartSimpleConvert;
import com.haoxuer.bigworld.tenant.data.entity.Tenant;
import com.haoxuer.discover.config.utils.ConverResourceUtils;
import com.haoxuer.discover.data.page.Filter;
import com.haoxuer.discover.data.page.Order;
import com.haoxuer.discover.data.page.Page;
import com.haoxuer.discover.data.page.Pageable;
import com.haoxuer.discover.data.utils.FilterUtils;
import com.nbsaas.nbmall.product.data.enums.ProductType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.haoxuer.bigworld.member.rest.conver.PageableConver;
import com.haoxuer.bigworld.tenant.util.TenantBeanUtils;
import com.nbsaas.nbmall.shop.data.dao.ShopDao;
import com.haoxuer.bigworld.member.data.dao.TenantUserDao;
import com.nbsaas.nbmall.product.data.dao.ProductDao;
import com.nbsaas.nbmall.product.data.dao.ProductSkuDao;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Transactional
@Component
public class CartResource implements CartApi {

    @Autowired
    private CartDao dataDao;

    @Autowired
    private ShopDao shopDao;
    @Autowired
    private TenantUserDao tenantUserDao;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private ProductSkuDao skuDao;


    @Override
    public CartResponse create(CartDataRequest request) {
        CartResponse result = new CartResponse();
        if (request.getTenantUser() == null) {
            result.setCode(501);
            result.setMsg("无效用户");
            return result;
        }
        if (request.getProduct() == null) {
            result.setCode(502);
            result.setMsg("无效产品");
            return result;
        }
        if (request.getAmount() == null) {
            request.setAmount(1);
        }
        Cart bean;
        if (request.getSku() != null) {
            bean = dataDao.one(Filter.eq("tenantUser.id", request.getTenantUser()),
                    Filter.eq("sku.id", request.getSku()),
                    Filter.eq("product.id", request.getProduct()));
        } else {
            bean = dataDao.one(Filter.eq("tenantUser.id", request.getTenantUser()),
                    Filter.eq("product.id", request.getProduct()));
        }

        if (bean == null) {
            bean = new Cart();
            bean.setTenant(Tenant.fromId(request.getTenant()));
            handleData(request, bean);
            dataDao.save(bean);
        } else {
            if (bean.getAmount() == null) {
                bean.setAmount(1);
            }
            Integer amount = bean.getAmount() + request.getAmount();
            bean.setAmount(amount);
        }

        if (bean.getSku() != null) {
            bean.setProductType(ProductType.sku);
            bean.setPrice(bean.getSku().getSalePrice());
        } else {
            bean.setProductType(ProductType.spu);
            bean.setPrice(bean.getProduct().getSalePrice());
        }

        if (bean.getPrice() == null) {
            bean.setPrice(new BigDecimal(0));
        }
        BigDecimal total = bean.getPrice().multiply(new BigDecimal(bean.getAmount()));
        bean.setTotal(total);

        result = new CartResponseConvert().conver(bean);
        return result;
    }

    @Override
    public CartResponse update(CartDataRequest request) {
        CartResponse result = new CartResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        Cart bean = dataDao.findById(request.getId());
        if (bean == null) {
            result.setCode(502);
            result.setMsg("无效id");
            return result;
        }
        handleData(request, bean);
        result = new CartResponseConvert().conver(bean);
        return result;
    }

    private void handleData(CartDataRequest request, Cart bean) {
        TenantBeanUtils.copyProperties(request, bean);
        if (request.getTenantUser() != null) {
            bean.setTenantUser(tenantUserDao.findById(request.getTenantUser()));
        }
        if (request.getShop() != null) {
            bean.setShop(shopDao.findById(request.getShop()));
        }
        if (request.getProduct() != null) {
            bean.setProduct(productDao.findById(request.getProduct()));
        }
        if (request.getSku() != null) {
            bean.setSku(skuDao.findById(request.getSku()));
        }

    }

    @Override
    public CartResponse delete(CartDataRequest request) {
        CartResponse result = new CartResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        dataDao.deleteById(request.getTenant(), request.getId());
        return result;
    }

    @Override
    public CartResponse view(CartDataRequest request) {
        CartResponse result = new CartResponse();
        Cart bean = dataDao.findById(request.getTenant(), request.getId());
        if (bean == null) {
            result.setCode(1000);
            result.setMsg("无效id");
            return result;
        }
        result = new CartResponseConvert().conver(bean);
        return result;
    }

    @Override
    public CartList list(CartSearchRequest request) {
        CartList result = new CartList();

        List<Filter> filters = new ArrayList<>();
        filters.add(Filter.eq("tenant.id", request.getTenant()));
        filters.addAll(FilterUtils.getFilters(request));
        List<Order> orders = new ArrayList<>();
        if ("asc".equals(request.getSortMethod())) {
            orders.add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            orders.add(Order.desc("" + request.getSortField()));
        } else {
            orders.add(Order.desc("id"));
        }
        List<Cart> organizations = dataDao.list(0, request.getSize(), filters, orders);

        CartSimpleConvert convert = new CartSimpleConvert();
        ConverResourceUtils.converList(result, organizations, convert);


        return result;
    }

    @Override
    public MapResponse my(CartSearchRequest request) {
        MapResponse result = new MapResponse();

        List<Filter> filters = new ArrayList<>();
        filters.add(Filter.eq("tenant.id", request.getTenant()));
        filters.addAll(FilterUtils.getFilters(request));
        List<Order> orders = new ArrayList<>();
        if ("asc".equals(request.getSortMethod())) {
            orders.add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            orders.add(Order.desc("" + request.getSortField()));
        } else {
            orders.add(Order.desc("id"));
        }
        List<Cart> organizations = dataDao.list(0, request.getSize(), filters, orders);

        CartSimpleConvert convert = new CartSimpleConvert();
        List<CartSimple> simples = ConverResourceUtils.converList(organizations, convert);
        Integer totalAmount = 0;
        BigDecimal totalMoney = new BigDecimal(0.00);
        Integer checkedAmount = 0;
        BigDecimal checkedMoney = new BigDecimal(0.00);

        if (simples!=null){
            for (CartSimple cart : simples) {
                totalAmount += cart.getAmount();
                totalMoney = totalMoney.add(cart.getPrice().multiply(new BigDecimal(cart.getAmount())));
                if (cart.getChecked()) {
                    checkedAmount += cart.getAmount();
                    checkedMoney = checkedMoney.add(cart.getPrice().multiply(new BigDecimal(cart.getAmount())));
                }
            }
        }
        result.put("totalAmount",totalAmount);
        result.put("totalMoney",totalMoney);
        result.put("checkedAmount",checkedAmount);
        result.put("checkedMoney",checkedMoney);
        result.put("list",simples);

        return result;
    }

    @Override
    public CartPage search(CartSearchRequest request) {
        CartPage result = new CartPage();
        Pageable pageable = new PageableConver().conver(request);
        pageable.getFilters().addAll(FilterUtils.getFilters(request));
        pageable.getFilters().add(Filter.eq("tenant.id", request.getTenant()));
        if ("asc".equals(request.getSortMethod())) {
            pageable.getOrders().add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            pageable.getOrders().add(Order.desc("" + request.getSortField()));
        } else {
            pageable.getOrders().add(Order.desc("id"));
        }
        Page<Cart> page = dataDao.page(pageable);

        CartSimpleConvert convert = new CartSimpleConvert();
        ConverResourceUtils.converPage(result, page, convert);
        return result;
    }
}
